package com.tianji.promotion.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.tianji.promotion.constants.PromotionConstants;
import com.tianji.promotion.domain.po.Coupon;
import com.tianji.promotion.domain.po.ExchangeCode;
import com.tianji.promotion.mapper.ExchangeCodeMapper;
import com.tianji.promotion.service.IExchangeCodeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.promotion.utils.CodeUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static com.tianji.promotion.constants.PromotionConstants.COUPON_CODE_MAP_KEY;

/**
 * <p>
 * 兑换码 服务实现类
 * </p>
 *
 * @author ltd
 * @since 2024-07-02
 */
@Service
@Slf4j
public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, ExchangeCode> implements IExchangeCodeService {
    private final   StringRedisTemplate redisTemplate;

    private final BoundValueOperations<String,String> serialOps;

    public ExchangeCodeServiceImpl(StringRedisTemplate redisTemplate){
         this.redisTemplate=redisTemplate;
         this.serialOps=redisTemplate.boundValueOps(PromotionConstants.COUPON_CODE_SERIAL_KEY);
    }

    @Override
    public void asyncGenerateCode(Coupon coupon) {
        //获取总共的发放数量 假如1000
        Integer totalNum = coupon.getTotalNum();

        //获取redis的id作为自增序列号从4000起
        Long increment = serialOps.increment(totalNum);
         try {
            if (ObjectUtil.isEmpty(increment)){
                return;
            }
            //5000
            int position = increment.intValue();
            //i=4001    position= 5000  totalNum=1000  |4001    5000

            List<ExchangeCode> exchangeCodeList=new ArrayList<>(totalNum);
            ExchangeCode exchangeCode = new ExchangeCode();
            for (int i=position-totalNum+1;i<=position;i++){
                //生成换码
                String code = CodeUtil.generateCode(i, coupon.getId());
                exchangeCode.setCode(code);
                exchangeCode.setId(i);
                exchangeCode.setExchangeTargetId(coupon.getId());
                exchangeCode.setExpiredTime(coupon.getIssueEndTime());

            }
            exchangeCodeList.add(exchangeCode);
            //存入数据库
            this.saveBatch(exchangeCodeList);
        } catch (Exception e) {
          serialOps.decrement(totalNum);
          throw e;
        }

    }

    @Override
    public Boolean getTheStatusOfTheRedemptionCode(long redeemCodes, boolean b) {
        Boolean aBoolean = redisTemplate.opsForValue().setBit(COUPON_CODE_MAP_KEY, redeemCodes, b);



        return aBoolean!=null&&aBoolean;
    }
}
